#include "Basic/FileSystem.h"

#include "shlwapi.h"
#pragma comment(lib,"shlwapi.lib")

namespace GxLibBasic
{

	bool FileExists(String FileName)
	{
		return (PathFileExistsW(FileName.GetStrPtr()) == TRUE);
	}

	void MakeDirectory(String & Dir)
	{
		if (Dir[Dir.GetLength()-1] == gxPathDelim || Dir[Dir.GetLength()-1] == gxPathDelim2)
		{
			return;
		}
		else
			Dir += gxPathDelim;
	}

	String ExtractFilePath(String fn)
	{
		int delimPos = -1;
		for (int i= fn.GetLength()-1; i>=0; i--)
		{
			if (fn[i] == gxPathDelim || fn[i] == gxPathDelim2)
			{
				delimPos = i;
				break;
			}
		}
		if (delimPos != -1)
		{
			return fn.Left(delimPos+1);
		}
		return L"";
	}

	bool SearchFile(String relPath, Array<String>& paths,String &result)
	{
		wchar_t buf[MAX_PATH];
		memset(buf,0,MAX_PATH*sizeof(wchar_t));
		LPCWSTR * dirs;
		dirs = new LPCWSTR[paths.Count()+1];
		for (int i=0; i<paths.Count(); i++)
			dirs[i] = const_cast<wchar_t *>(paths[i].GetStrPtr());
		dirs[paths.Count()] = 0;
		wcscpy_s(buf,MAX_PATH,relPath.GetStrPtr());
		PathFindOnPathW(buf, dirs);
		wchar_t fullPath[MAX_PATH];
		memset(fullPath,0,MAX_PATH*sizeof(wchar_t));
		GetFullPathName(buf,MAX_PATH,fullPath,0);
		result = fullPath;
		delete [] dirs;
		return FileExists(result);
	}

	void ConvertPathDelim(String & fname)
	{
		for (int i=0; i<fname.GetLength(); i++)
		{
			if (fname[i] == L'/')
				fname[i] = L'\\';
		}
	}

	String GetFullFileName(String fname)
	{
		wchar_t fullPath[MAX_PATH];
		memset(fullPath,0,MAX_PATH*sizeof(wchar_t));
		GetFullPathName(fname.GetStrPtr(),MAX_PATH,fullPath,0);
		String result = fullPath;
		return result;
	}

	String ExtractFileEXT(String fname)
	{
		int dotpos = -1;
		for (int i=fname.GetLength()-1; i>=0; i--)
			if (fname[i] == L'.')
			{
				dotpos = i;
				break;
			}
		if (dotpos!=-1)
			return fname.Right(fname.GetLength()-1-dotpos);
		else
			return L"";
	}

	String ExtractFileNameWithoutEXT(String fname)
	{
		int delimPos = -1;
		for (int i= fname.GetLength()-1; i>=0; i--)
		{
			if (fname[i] == gxPathDelim || fname[i] == gxPathDelim2)
			{
				delimPos = i;
				break;
			}
		}
		int dotPos = -1;
		for (int i= fname.GetLength()-1; i>=0; i--)
		{
			if (fname[i] == L'.')
			{
				dotPos = i;
				break;
			}
		}
		String rs = fname;
		if (delimPos != -1)
		{
			rs = fname.Right(fname.GetLength()-delimPos-1);
		}
		if (dotPos != -1)
			rs = rs.Left(dotPos-delimPos-1);
		return rs;
	}

	String ExtractFileName(String fname)
	{
		int delimPos = -1;
		for (int i= fname.GetLength()-1; i>=0; i--)
		{
			if (fname[i] == gxPathDelim || fname[i] == gxPathDelim2)
			{
				delimPos = i;
				break;
			}
		}
		int dotPos = -1;
		for (int i= fname.GetLength()-1; i>=0; i--)
		{
			if (fname[i] == L'.')
			{
				dotPos = i;
				break;
			}
		}
		String rs = fname;
		if (delimPos != -1)
		{
			rs = fname.Right(fname.GetLength()-delimPos-1);
		}
		return rs;
	}

	gxFileIterator::gxFileIterator(const String &path, const String &fileMask, bool _findDir)
	{
		WIN32_FIND_DATA find;
		findDir = _findDir;
		handle = FindFirstFileW((path+L"./"+fileMask).GetStrPtr(), &find);
		eof = (handle == INVALID_HANDLE_VALUE);
		if (!eof)
		{
			isDir = ((find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0);
			curFileName = find.cFileName;
		}
		while (!eof)
		{
			if (isDir && !findDir)
			{
				eof = (FindNextFile(handle, &find)==0);
				if (!eof)
				{
					isDir = ((find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0);
					curFileName = find.cFileName;
				}
			}
			else
				break;
		}
		
	}

	gxFileIterator::~gxFileIterator()
	{
		FindClose(handle);
	}

	bool gxFileIterator::MoveNext()
	{
		if (!eof)
		{
			WIN32_FIND_DATA find;
			eof = (FindNextFile(handle, &find)==0);
			if (!eof)
			{
				isDir = ((find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0);
				curFileName = find.cFileName;
			}
			while (!eof)
			{
				if (isDir && !findDir)
				{
					eof = (FindNextFile(handle, &find)==0);
					if (!eof)
					{
						isDir = ((find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0);
						curFileName = find.cFileName;
					}
				}
				else
					break;
			}
			return eof;
		}
		else
			return false;
	}

	bool gxFileIterator::IsEnd()
	{
		return eof;
	}

	String gxFileIterator::GetCurrentFileName()
	{
		return curFileName;
	}

	bool gxFileIterator::IsDirectory()
	{
		return isDir;
	}

}